﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using wh40klbWeb.Models;
using wh40klbModel;
using System.Data.Entity.Validation;

namespace wh40klbWeb.Controllers
{
    public class InfantryController : Controller
    {
        private WarhammerContext context = new WarhammerContext();



        public ActionResult ListAll()
        {
            List<InfantryViewModel> infantries = context
                .Infantries

                .Select(i => new InfantryViewModel
                {
                    Name = i.Name,
                    WeaponSkill = i.WeaponSkill,
                    BallisticSkill = i.BallisticSkill,
                    Strengh = i.Strengh,
                    Thoughness = i.Thoughness,
                    Wounds = i.Wounds,
                    Initiative = i.Initiative,
                    Attack = i.Attack,
                    Leadership = i.Leadership,
                    ArmorSave = i.ArmorSave,
                    Description = i.Description,
                    Id = i.Id,
                    Army = new ArmyViewModel
                    {
                        Name = i.Army.Name,
                        Id=i.ArmyId
                    },
                    SquadTypeSelected = i.SquadTypeId,
                    SquadType = i.SquadType.Name,
                    Availible = i.Army.availible && i.availible ? "Availible" : "notAvailible"
                })
                .OrderBy(i => i.Army.Name)
                .ThenBy(i => i.SquadTypeSelected)
                .ThenBy(i => i.Name)
                .ToList();

            return View(infantries);
        }
        public ActionResult Index(int id)
        {
            ViewBag.armyId = id;
            Army a = context.Armies
                .Find(id);
            context.Entry(a).Collection(ar => ar.Infantries).Load();
            List<InfantryViewModel> infantries = a
                .Infantries
                .Where(i => i.availible)
                .OrderBy(i => i.SquadTypeId).ThenBy(i => i.Name)
                .Select(i => new InfantryViewModel
                {
                    Name = i.Name,
                    WeaponSkill = i.WeaponSkill,
                    BallisticSkill = i.BallisticSkill,
                    Strengh = i.Strengh,
                    Thoughness = i.Thoughness,
                    Wounds = i.Wounds,
                    Initiative = i.Initiative,
                    Attack = i.Attack,
                    Leadership = i.Leadership,
                    ArmorSave = i.ArmorSave,
                    Description = i.Description,
                    Id = i.Id
                })
                .ToList();
            return PartialView(infantries);
        }
        public ActionResult Details(int id)
        {
            InfantryViewModel ivm = context.Infantries.Where(i => i.Id == id && i.availible).Select(i => new InfantryViewModel
            {
                ArmorSave = i.ArmorSave,
                Attack = i.Attack,
                BallisticSkill = i.BallisticSkill,
                Description = i.Description,
                Initiative = i.Initiative,
                Leadership = i.Leadership,
                Name = i.Name,
                SquadType = i.SquadType.Name,
                Strengh = i.Strengh,
                Thoughness = i.Thoughness,
                WeaponSkill = i.WeaponSkill,
                Wounds = i.Wounds,
                Id = i.Id
            }).FirstOrDefault();
            if (ivm == null) return RedirectToAction("Index", "Army");
            ivm.Army = context.Armies.Where(a => a.Infantries.Count(i => i.Id == id) > 0 && a.availible).Select(a => new ArmyViewModel
            {
                Id = a.Id
            }).FirstOrDefault();
            if (ivm.Army == null) return RedirectToAction("Index", "Army");
            return View(ivm);
        }


        public ActionResult Create(int id)
        {
            Army army = context.Armies.Find(id);
            List<SpecialRuleViewModel> srvms = context
                .SpecialRules
                .Where(sr => (sr.Armies.Count == 0 || sr.Armies.Count(a => a.Id == id && a.availible) > 0) && sr.availible)
                .Select(sr => new SpecialRuleViewModel()
                {
                    Name = sr.Name,
                    Description = sr.Description,
                    Id = sr.Id
                })
                .OrderBy(sr => sr.Name.ToLower())
                .ToList();
            List<SquadTypeViewModel> sqTypes = context
                .SquadTypes
                .Where(st => st.ArmySquadTypeUseds.Count(astu => astu.ArmyId == id) > 0 && st.availible)
                .Select(st => new SquadTypeViewModel() { Id = st.Id, Name = st.Name }).ToList();



            InfantryViewModel ivm = new InfantryViewModel()
            {
                Army = new ArmyViewModel
                {
                    Id = army.Id,
                    Name = army.Name
                },
                SpecialRules = srvms,
                SquadTypes = sqTypes
            };
            return View(ivm);
        }
        [HttpPost]
        public ActionResult Create(int id, InfantryViewModel infantryToCreate)
        {
            try
            {
                if (!ModelState.IsValid) throw new Exception("une erreur de modelstate s'est produite");

                Infantry infantryCreated = new Infantry
                {
                    Name = infantryToCreate.Name,
                    WeaponSkill = infantryToCreate.WeaponSkill,
                    BallisticSkill = infantryToCreate.BallisticSkill,
                    Strengh = infantryToCreate.Strengh,
                    Thoughness = infantryToCreate.Thoughness,
                    Wounds = infantryToCreate.Wounds,
                    Initiative = infantryToCreate.Initiative,
                    Attack = infantryToCreate.Attack,
                    Leadership = infantryToCreate.Leadership,
                    ArmorSave = infantryToCreate.ArmorSave,
                    Description = infantryToCreate.Description,
                    availible = true,
                    Army = context.Armies.Find(infantryToCreate.Army.Id),
                    SquadType = context.SquadTypes.Find(infantryToCreate.SquadTypeSelected)
                };


                foreach (var item in infantryToCreate.SpecialRules.Where(sru => sru.Selected))
                {
                    infantryCreated.SpecialRules.Add(context.SpecialRules.Find(item.Id));
                }


                infantryCreated.Army.Infantries.Add(infantryCreated);



                context.Entry(infantryCreated).State = System.Data.EntityState.Added;
                context.Entry(infantryCreated.Army).State = System.Data.EntityState.Modified;
                context.SaveChanges();
                return RedirectToAction("Details", "Army", new { id = infantryToCreate.Army.Id });
            }
            catch (Exception exception)
            {
                ViewBag.Erreur = exception.Message;
                List<SquadTypeViewModel> sqTypes = context
                    .SquadTypes
                    .Where(st => st.ArmySquadTypeUseds.Count(astu => astu.ArmyId == id) > 0)
                    .Select(st => new SquadTypeViewModel() { Id = st.Id, Name = st.Name }).ToList();
                int stcount = sqTypes.Count;
                infantryToCreate.SquadTypes = sqTypes;
                return View(infantryToCreate);
            }
        }


        public ActionResult Edit(int id)
        {
            InfantryViewModel ivm = context.Infantries.Where(i => i.Id == id && i.availible).Select(i => new InfantryViewModel
            {
                ArmorSave = i.ArmorSave,
                Attack = i.Attack,
                BallisticSkill = i.BallisticSkill,
                Description = i.Description,
                Initiative = i.Initiative,
                Leadership = i.Leadership,
                Name = i.Name,
                SquadType = i.SquadType.Name,
                Strengh = i.Strengh,
                Thoughness = i.Thoughness,
                WeaponSkill = i.WeaponSkill,
                Wounds = i.Wounds
            }).FirstOrDefault();
            if (ivm == null) return RedirectToAction("Index", "Army");
            ivm.Army = context.Armies.Where(a => a.Infantries.Count(i => i.Id == id) > 0 && a.availible).Select(a => new ArmyViewModel
            {
                Id = a.Id
            }).FirstOrDefault();
            if (ivm.Army == null) return RedirectToAction("Index", "Army");

            List<SpecialRuleViewModel> srvms = context
                .SpecialRules
                .Where(sr => (sr.Armies.Count == 0 || sr.Armies.Count(a => a.Id == ivm.Army.Id && a.availible) > 0) && sr.availible)
                .Select(sr => new SpecialRuleViewModel()
                    {
                        Name = sr.Name,
                        Description = sr.Description,
                        Id = sr.Id,
                        Selected=context.Infantries.Count(i=>i.availible && i.SpecialRules.Count(s=>s.Id==sr.Id)>0)>0
                    }
                )
                .OrderBy(sr => sr.Name.ToLower())
                .ToList();
            List<SquadTypeViewModel> sqTypes = context
                .SquadTypes
                .Where(st => st.ArmySquadTypeUseds.Count(astu => astu.ArmyId == ivm.Army.Id) > 0 && st.availible)
                .Select(st => new SquadTypeViewModel() { Id = st.Id, Name = st.Name }).ToList();

            ivm.SquadTypes = sqTypes;
            ivm.SpecialRules = srvms;

            return View(ivm);
        }
        [HttpPost]
        public ActionResult Edit(int id, InfantryViewModel infantryToEdit)
        {
            try
            {
                if (!ModelState.IsValid) throw new Exception("une erreur de modelstate s'est produite");

                Infantry infantryEdited = new Infantry { Id = infantryToEdit.Id };
                context.Infantries.Attach(infantryEdited);


                infantryEdited.ArmorSave = infantryToEdit.ArmorSave;
                infantryEdited.Attack = infantryToEdit.Attack;
                infantryEdited.availible = true;
                infantryEdited.BallisticSkill = infantryToEdit.BallisticSkill;
                infantryEdited.Description = infantryToEdit.Description;
                infantryEdited.Initiative = infantryToEdit.Initiative;
                infantryEdited.Leadership = infantryToEdit.Leadership;
                infantryEdited.Name = infantryToEdit.Name;
                infantryEdited.SquadType = context.SquadTypes.Find(infantryToEdit.SquadTypeSelected);
                infantryEdited.Strengh = infantryToEdit.Strengh;
                infantryEdited.Thoughness = infantryToEdit.Thoughness;
                infantryEdited.WeaponSkill = infantryToEdit.WeaponSkill;
                infantryEdited.Wounds = infantryToEdit.Wounds;
                infantryEdited.Army = context.Armies.Find(infantryToEdit.Army.Id);

                context.Entry(infantryEdited).Collection("SpecialRules").Load();

                foreach (var item in infantryToEdit.SpecialRules)
                {

                    if (item.Selected)
                    {
                        if (infantryEdited.SpecialRules.Count(sr => sr.Id == item.Id) == 0)
                        {
                            SpecialRule specialRule = new SpecialRule { Id = item.Id };
                            context.SpecialRules.Attach(specialRule);
                            infantryEdited.SpecialRules.Add(specialRule);
                        }
                    }
                    else
                    {
                        if (infantryEdited.SpecialRules.Count(sr => sr.Id == item.Id) > 0)
                        {
                            SpecialRule specialRule = infantryEdited.SpecialRules.FirstOrDefault(i => i.Id == item.Id);
                            infantryEdited.SpecialRules.Remove(specialRule);
                        }
                    }
                }


                context.Entry(infantryEdited).State = System.Data.EntityState.Modified;
                context.SaveChanges();
                return RedirectToAction("Details", "Infantry", new { id = infantryToEdit.Id });
            }
            catch (DbEntityValidationException e)
            {
                ViewBag.Erreur = e.Message;
                List<SquadTypeViewModel> sqTypes = context
                    .SquadTypes
                    .Where(st => st.ArmySquadTypeUseds.Count(astu => astu.ArmyId == id) > 0)
                    .Select(st => new SquadTypeViewModel() { Id = st.Id, Name = st.Name }).ToList();
                int stcount = sqTypes.Count;
                infantryToEdit.SquadTypes = sqTypes;
                return View(infantryToEdit);
            }
            catch (Exception exception)
            {

                ViewBag.Erreur = exception.Message;
                List<SquadTypeViewModel> sqTypes = context
                    .SquadTypes
                    .Where(st => st.ArmySquadTypeUseds.Count(astu => astu.ArmyId == id) > 0)
                    .Select(st => new SquadTypeViewModel() { Id = st.Id, Name = st.Name }).ToList();
                int stcount = sqTypes.Count;
                infantryToEdit.SquadTypes = sqTypes;
                return View(infantryToEdit);
            }
        }


        public ActionResult Delete(int id)
        {
            InfantryViewModel ivm = context.Infantries.Where(i => i.Id == id && i.availible).Select(i => new InfantryViewModel
            {
                ArmorSave = i.ArmorSave,
                Attack = i.Attack,
                BallisticSkill = i.BallisticSkill,
                Description = i.Description,
                Initiative = i.Initiative,
                Leadership = i.Leadership,
                Name = i.Name,
                SquadType = i.SquadType.Name,
                Strengh = i.Strengh,
                Thoughness = i.Thoughness,
                WeaponSkill = i.WeaponSkill,
                Wounds = i.Wounds,
                Army = new ArmyViewModel { Id = i.ArmyId }
            }).FirstOrDefault();
            if (ivm == null) return RedirectToAction("Index", "Army");


            return View(ivm);
        }
        [HttpPost]
        public ActionResult Delete(int id, InfantryViewModel infantryToDelete)
        {

            try
            {
                Infantry inf = context.Infantries.Find(infantryToDelete.Id);

                context.Entry(inf).Collection("Squads").Load();
                foreach (var item in inf.Squads)
                {
                    item.availible = false;
                    context.Entry(item).State = System.Data.EntityState.Modified;
                }
                context.Entry(inf).Collection("Wargears").Load();
                foreach (var item in inf.Squads)
                {
                    item.availible = false;
                    context.Entry(item).State = System.Data.EntityState.Modified;
                }



                inf.availible = false;
                context.Entry(inf).State = System.Data.EntityState.Modified;
                context.SaveChanges();
                return RedirectToAction("Details", "Army", new { id = infantryToDelete.Army.Id });
            }
            catch
            {
                return View();
            }
        }
    }
}
